Csrf.php
<?php
namespace Tlf\User\Test\Gui;
class Csrf extends \Tlf\User\GuiTester {
public function testSubmitResetWithCsrfCheck(){
//////
// get session id
//////
$response = $this->curl_get('/user/reset-password/', ['enable_csrf'=>true]);
$content = $response['body'];
$session_id = $response['cookies']['PHPSESSID']['value'];
// $csrf = json_decode($content, true);
// get the csrf key & code
$doc = new \Taeluf\PHTML($response['body']);
$node = $doc->xpath('//input[@type="hidden"]', $refNode=null)[0];
$csrf_key = $node->name;
$csrf_code = $node->value;
//////
// test the POST
//////
$lib = new \Tlf\User\Lib($this->pdo());
$email = 'reed@reset.password.csrf';
$user = $this->get_active_user($email, 'abc');
$response = $this->curl_post('/user/reset-password/',
[
'email'=>$email,
'test_spoof_ip'=>'reqpasschange.csrf',
$csrf_key=>$csrf_code,
'enable_csrf'=>true,
'logs_consent'=>'on',
],
$files=[],'backward_compat',
[
'REFERER: '.$this->cli->get_server_host(),
'Cookie'=> 'PHPSESSID='.$session_id,
]
);
$response = $response['body'];
// echo $response;
// exit;
$this->test("Response");
$msg = sprintf('An email has been sent to %s. Please check your email to finish resetting your password', $email);
$this->str_contains($response,$msg);
$this->str_not_contains($response,'<form');
$this->test("Email message");
$msg = $this->get_email();
$user = $lib->user_from_email($email);
$ldb = new \Tlf\LilDb($this->pdo());
$code_rows = $ldb->select('code',['user_id'=>$user->id, 'type'=>'password_reset']);
$reset_code = $code_rows[0]['code'];
$target_url = 'http://create.localhost/user/complete.password_reset.'.$reset_code.'/';
$target_msg = "To setup a new password, visit <a href=\"$target_url\">$target_url</a>.";
$this->compare($target_msg,$msg);
// i will likely later write a test that is the entire flow
//
// $login_code = $user->password_login('abc');
// $this->is_string($login_code);
//
// $complete_reset_form = $this->get('/complete.password_reset.'.$reset_code.'/');
//
//
// $this->is_false($user->password_login('abc'));
}
public function testCsrfSpoofNoPost(){
$bad_response = $this->post('/csrf-test-post/', [],
);
echo $bad_response;
$this->str_contains(
$bad_response,
'csrf post test success'
);
}
public function testCsrfSpoof(){
$bad_response = $this->post('/csrf-test-post/', ['csrf-test-csrf-random_code'=>'fake_code'],
);
$this->str_contains(
$bad_response,
'csrf post test success'
);
}
public function testValidateCsrf(){
$response = $this->curl_post('/csrf-test/', ['enable_csrf'=>true]);
$content = $response['body'];
$session_id = $response['cookies']['PHPSESSID']['value'];
$csrf = json_decode($content, true);
$bad_response = $this->curl_post('/csrf-test-post/', [$csrf['key']=>null, 'enable_csrf'=>true],
$files=[],'backward_compat',
[
'REFERER: '.$this->cli->get_server_host(),
'Cookie'=> 'PHPSESSID='.$session_id,
]
);
$this->str_contains(
$bad_response['body'],
'csrf post test not valid'
);
echo "\n\nInvalid Response:\n".$bad_response['body'];
$good_response = $this->curl_post('/csrf-test-post/', [$csrf['key']=>$csrf['code'], 'enable_csrf'=>true],
$files=[],'backward_compat',
[
'REFERER: '.$this->cli->get_server_host(),
'Cookie'=> 'PHPSESSID='.$session_id,
]
);
$this->str_contains($good_response['body'],
'csrf post test success'
);
echo "\n\nGood Response:\n".$good_response['body'];
}
public function testGenCsrf(){
$content = $this->get('/csrf-test/', ['enable_csrf'=>true]);
$csrf = json_decode($content, true);
$this->is_string($csrf['code']);
$this->is_true($csrf['expires_at'] > time());
$this->is_true($csrf['expires_at'] < time() + 60 * 10 + 1);
$this->compare($csrf['uri'], '/csrf-test-post/');
}
}